using System;
using NUnit.Framework;
using ValidationFramework.Extensions;

namespace ValidationFramework.Tests
{
    [TestFixture]
    public class CompareNumberRuleAttributeTest
    {

        [Test]
        public void RunForAllNumberTypes()
        {
            CheckDefaultValues<byte>(2);
            CheckDefaultValues(2);
            CheckDefaultValues<long>(2);
            CheckDefaultValues<double>(2);
            CheckDefaultValues<float>(2);
            CheckDefaultValues<short>(2);
            CallAttributeTester<byte>(2);
            CallAttributeTester(2);
            CallAttributeTester<long>(2);
            CallAttributeTester<double>(2);
            CallAttributeTester<float>(2);
            CallAttributeTester<short>(2);
        }


        public void CheckDefaultValues<T>(T initialValue) where T : IComparable<T>
        {
            var ruleAttribute = CreateRuleAttribute(initialValue);
            

            var propertyRule = (CompareRule<T>)ruleAttribute.CreateRule(new MockPropertyDescriptor<byte>("foo"));
            var parameterRule = (CompareRule<T>)ruleAttribute.CreateRule(new MockParameterDescriptor<byte>("foo"));
            Assert.AreEqual(initialValue, TypeHelper.GetPropertyValue<T>(ruleAttribute,"ValueToCompare"));
            Assert.AreEqual(CompareOperator.Equal, ruleAttribute.Operator);

            Assert.AreEqual(CompareOperator.Equal, parameterRule.CompareOperator);
            Assert.AreEqual(initialValue, propertyRule.ValueToCompare);

            Assert.AreEqual(CompareOperator.Equal, propertyRule.CompareOperator);
            Assert.AreEqual(initialValue, parameterRule.ValueToCompare);

        }
      
        public void CallAttributeTester<T>(T initialValue) where T : IComparable<T>
        {
			AttributeTester.CheckDefaultValues<T>(CreateRuleAttribute(initialValue), true, true);
			AttributeTester.CheckNonDefaultValues<T>(CreateRuleAttribute(initialValue), true, true);
        }

        private static CompareRuleAttribute CreateRuleAttribute<T>(T initialValue) where T : IComparable<T>
        {
            var attributeTypeName = string.Format("ValidationFramework.Compare{0}RuleAttribute,ValidationFramework", TypeHelper.GetTypeFromKeyName<T>());
            var attributeType = Type.GetType(attributeTypeName);

            var constructorInfo = attributeType.GetPublicInstanceConstructor( typeof(T), typeof(CompareOperator));
            return (CompareRuleAttribute)constructorInfo.Invoke(new object[]{ initialValue, CompareOperator.Equal});
        }


    
    }
}